﻿
using GcExcelDemoTest.spread_templates;
using Huozima.ExcelEngine;
using System.Data;
using System.IO;
using System.Reflection;
using System.Runtime.Loader;
using System.Text;
internal partial class  Program
{
    static void Main(string[] args)
    {
        //Console.WriteLine("GrapeCity Excel 动态库的const string");        
        //Main_GET_CONST_STRING();
        //Console.WriteLine("================================\n");
        //Console.WriteLine("GrapeCity Excel 反编译代码分析");
        Console.WriteLine("================================\n");
        //Main_FIND_StartObjectTag();

        // 现在尝试打开问题模板文件
        //Console.WriteLine("\n=== 尝试打开问题模板文件 ===");
        //TestProblematicTemplate();

        //Console.WriteLine("\n=== 简单模板文件测试 ===");
        //Main_Simple_test();
        //Console.WriteLine("\n按任意键退出...");
        //Console.WriteLine("\n=== 简单交叉扩展文件测试 ===");
        //Main_test02();
        //Console.WriteLine("\n按任意键退出...");

        //Console.WriteLine("\n=== 条件格式文件测试 ===");
        //Main_test03();
        //Console.WriteLine("\n按任意键退出...");
        TestCase.Main_JsonDataImageTemplate();
        TestCase.Main_JsonFile();
        Console.WriteLine("\n按任意键退出...");
        Console.ReadKey();
    }
    
    static void TestProblematicTemplate()
    {
        try
        {
            Console.WriteLine("正在测试问题模板文件...");
            
            var workbook = new Huozima.ExcelEngine.Workbook();
            var templateFile = GetResourceStream("xlsx\\template_datasource_variable.xlsx");
            
            if (templateFile == null)
            {
                Console.WriteLine("❌ 模板文件获取失败");
                return;
            }
            
            Console.WriteLine($"模板文件大小: {templateFile.Length} 字节");
            Console.WriteLine("⚠️  即将调用 workbook.Open() - 预期会发生异常");
            
            workbook.Open(templateFile); 
            Console.WriteLine("✅ 意外成功！模板文件打开成功");
            
        }
        catch (NullReferenceException ex)
        {
            Console.WriteLine("❌ 确认发生空引用异常:");
            Console.WriteLine($"   消息: {ex.Message}");
            Console.WriteLine("   这确实是反编译代码中的问题！");
            
            // 分析异常堆栈中的关键信息
            AnalyzeExceptionStack(ex);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"❌ 其他异常: {ex.GetType().Name}");
            Console.WriteLine($"   消息: {ex.Message}");
        }
    }
    
    static void AnalyzeExceptionStack(NullReferenceException ex)
    {
        Console.WriteLine("\n🔍 异常堆栈分析:");
        
        var stackTrace = ex.StackTrace;
        if (stackTrace != null)
        {
            var lines = stackTrace.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
            
            foreach (var line in lines.Take(3)) // 只分析前3层
            {
                if (line.Contains("evo.ad"))
                {
                    Console.WriteLine($"   🎯 问题方法: {line.Trim()}");
                    Console.WriteLine($"      这很可能是反编译时 m_bl 字段初始化逻辑丢失");
                }
                else if (line.Contains("Drawing"))
                {
                    Console.WriteLine($"   🎨 绘图模块: {line.Trim()}");
                    Console.WriteLine($"      绘图对象的依赖链可能在反编译时出错");
                }
                else
                {
                    Console.WriteLine($"   📍 调用链: {line.Trim()}");
                }
            }
        }
        

        
        // 生成详细的修复建议
        Console.WriteLine("\n");

    }


    static void Main_Simple_test()
    {
        //create a new workbook
        var workbook = new Huozima.ExcelEngine.Workbook();

        //Load template file template_datasource_variable.xlsx from resource
        var templateFile = GetResourceStream("xlsx\\template_datasource_variable.xlsx");
        workbook.Open(templateFile);

        var className = "Class 3";
        int count = 500;
        //Add data source
        workbook.AddDataSource("cName", className);
        workbook.AddDataSource("count", count);
        workbook.AddDataSource("owner", "Hunter Liu");
        //Invoke to process the template
        workbook.ProcessTemplate();

        // Save to an excel file
        workbook.Save("template_datasource_variable_output.xlsx");

    }

    static Stream GetResourceStream(string resourcePath)
    {
        string resource = "GcExcelDemoTest.Resource." + resourcePath.Replace("\\", ".");
        var assembly = typeof(Program).GetTypeInfo().Assembly;
        return assembly.GetManifestResourceStream(resource);
    }





    ////////////////////
    static void Main_GET_CONST_STRING()
    {
        string dllPath = @"D:\gitee\GrapeCity_CodeBuddy\dll\GcDocs.Excel.dll";
        string outputCsvPath = @"D:\gitee\GrapeCity_CodeBuddy\dll\const_strings.csv";

        if (!File.Exists(dllPath))
        {
            Console.WriteLine($"错误: DLL 文件不存在 - {dllPath}");
            return;
        }

        var context = new AssemblyLoadContext("ConstStringLoader", isCollectible: true);

        // 自动解析同目录下的依赖项
        context.Resolving += (ctx, assemblyName) =>
        {
            string dir = Path.GetDirectoryName(dllPath);
            string candidate = Path.Combine(dir, assemblyName.Name + ".dll");
            if (File.Exists(candidate))
                return ctx.LoadFromAssemblyPath(candidate);

            candidate = Path.Combine(dir, assemblyName.Name + ".exe");
            if (File.Exists(candidate))
                return ctx.LoadFromAssemblyPath(candidate);

            return null;
        };

        var results = new List<ConstStringInfo>();

        try
        {
            Assembly assembly = context.LoadFromAssemblyPath(dllPath);

            Type[] types;
            try
            {
                types = assembly.GetTypes();
            }
            catch (ReflectionTypeLoadException ex)
            {
                Console.WriteLine("警告: 部分类型无法加载，仅处理成功加载的类型。");
                types = ex.Types.Where(t => t != null).ToArray();
            }

            foreach (Type type in types)
            {
                var fields = type.GetFields(
                    BindingFlags.Public |
                    BindingFlags.NonPublic |
                    BindingFlags.Static |
                    BindingFlags.FlattenHierarchy);

                var constStringFields = fields
                    .Where(f => f.IsLiteral && !f.IsInitOnly && f.FieldType == typeof(string))
                    .ToArray();

                foreach (var field in constStringFields)
                {
                    try
                    {
                        string value = (string)field.GetValue(null);
                        results.Add(new ConstStringInfo
                        {
                            TypeName = type.FullName,
                            Namespace = type.Namespace ?? "",
                            FieldName = field.Name,
                            Value = value ?? "",
                            Visibility = GetVisibility(field)
                        });
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"警告: 无法读取字段 {type.FullName}.{field.Name} - {ex.Message}");
                        // 仍记录，但值为空
                        results.Add(new ConstStringInfo
                        {
                            TypeName = type.FullName,
                            Namespace = type.Namespace ?? "",
                            FieldName = field.Name,
                            Value = "[ERROR_READING_VALUE]",
                            Visibility = GetVisibility(field)
                        });
                    }
                }
            }

            // 导出到 CSV
            ExportToCsv(results, outputCsvPath);
            Console.WriteLine($"成功导出 {results.Count} 个 const string 字段到: {outputCsvPath}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"严重错误: {ex}");
        }
        finally
        {
            context.Unload();
        }
    }
    static string GetVisibility(FieldInfo field)
    {
        if (field.IsPublic) return "public";
        if (field.IsFamily) return "protected";
        if (field.IsFamilyAndAssembly) return "private protected";
        if (field.IsFamilyOrAssembly) return "protected internal";
        return "private";
    }

    static void ExportToCsv(List<ConstStringInfo> data, string filePath)
    {
        var csv = new StringBuilder();
        // 写入表头（使用英文，避免编码问题）
        csv.AppendLine("Namespace,TypeName,FieldName,Visibility,Value");

        foreach (var item in data.OrderBy(x => x.Namespace).ThenBy(x => x.TypeName).ThenBy(x => x.FieldName))
        {
            // CSV 转义：如果值包含逗号、引号或换行，需要用双引号包裹，并转义内部引号
            string escapedValue = EscapeCsvField(item.Value);
            string escapedNamespace = EscapeCsvField(item.Namespace);
            string escapedTypeName = EscapeCsvField(item.TypeName);
            string escapedFieldName = EscapeCsvField(item.FieldName);
            string escapedVisibility = EscapeCsvField(item.Visibility);

            csv.AppendLine($"{escapedNamespace},{escapedTypeName},{escapedFieldName},{escapedVisibility},{escapedValue}");
        }

        File.WriteAllText(filePath, csv.ToString(), Encoding.UTF8);
    }

    static string EscapeCsvField(string field)
    {
        if (string.IsNullOrEmpty(field))
            return "";

        // 如果包含特殊字符，则用双引号包裹，并将内部双引号转义为两个双引号
        if (field.Contains(",") || field.Contains("\"") || field.Contains("\n") || field.Contains("\r"))
        {
            return "\"" + field.Replace("\"", "\"\"") + "\"";
        }

        return field;
    }


    static void Main_FIND_StartObjectTag()
    {
        string dllPath = @"D:\gitee\GrapeCity_CodeBuddy\dll\GcDocs.Excel.dll";
        string searchString = "StartObjectTag";

        if (!File.Exists(dllPath))
        {
            Console.WriteLine("DLL 文件不存在！");
            return;
        }

        try
        {
            byte[] fileBytes = File.ReadAllBytes(dllPath);
            byte[] searchBytes = Encoding.UTF8.GetBytes(searchString);

            bool found = ByteArrayContains(fileBytes, searchBytes);

            if (found)
            {
                Console.WriteLine($"在 DLL 中找到了字符串: {searchString}");
            }
            else
            {
                Console.WriteLine($"未在 DLL 中找到字符串: {searchString}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"读取文件时出错: {ex.Message}");
        }
    }

    static bool ByteArrayContains(byte[] source, byte[] pattern)
    {
        if (pattern.Length == 0) return true;
        if (source.Length < pattern.Length) return false;

        for (int i = 0; i <= source.Length - pattern.Length; i++)
        {
            bool found = true;
            for (int j = 0; j < pattern.Length; j++)
            {
                if (source[i + j] != pattern[j])
                {
                    found = false;
                    break;
                }
            }
            if (found) return true;
        }
        return false;
    }



    static void Main_test02()
    {
        //Get data from json file
        string jsonText = string.Empty;
        using (Stream stream = GetResourceStream("data.json"))
        using (StreamReader reader = new StreamReader(stream))
        {
            jsonText = reader.ReadToEnd();
        }
        // Create a JsonDataSource
        var datasource = new Huozima.ExcelEngine.JsonDataSource(jsonText);

        Dictionary<string, string> dict_template = new Dictionary<string, string>();
        dict_template.Add("xlsx\\TemplateAttribute_Expansion_cross.xlsx", "TemplateAttribute_Expansion_cross_Output.xlsx");
        dict_template.Add("xlsx\\TemplateAttribute_Expansion_cross02.xlsx", "TemplateAttribute_Expansion_cross02_Output.xlsx");
        dict_template.Add("xlsx\\TemplateAttribute_Expansion_cross03.xlsx", "TemplateAttribute_Expansion_cross03_Output.xlsx");
        dict_template.Add("xlsx\\TemplateAttribute_Expansion_cross04.xlsx", "TemplateAttribute_Expansion_cross04_Output.xlsx");
        foreach (var item in dict_template)
        {

            string str_template_file = item.Key;
            string str_output_file = item.Value;

            //create a new workbook
            var workbook = new Huozima.ExcelEngine.Workbook();

            //Load template file Template_Score.xlsx from resource
            var templateFile = GetResourceStream(str_template_file);
            XlsxOpenOptions openOptionsBase = new XlsxOpenOptions();
            openOptionsBase.DoNotAutoFitAfterOpened = false;
            workbook.Open(templateFile);

            //Add data source
            workbook.AddDataSource("ds", datasource);
            //Invoke to process the template
            workbook.ProcessTemplate();

            // Save to an excel file
            workbook.Save(str_output_file);
        }

    }


    static void Main_test03( )
    {
        //create a new workbook
        var workbook = new Huozima.ExcelEngine.Workbook();

        //Load template file from resource
        var templateFile = GetResourceStream("xlsx\\Template_WorkWithConditionalFormatting.xlsx");
        workbook.Open(templateFile);

        #region Init Data
        var datasource = new  DataTable();
        datasource.Columns.Add(new DataColumn("Area", typeof(string)));
        datasource.Columns.Add(new DataColumn("City", typeof(string)));
        datasource.Columns.Add(new DataColumn("Category", typeof(string)));
        datasource.Columns.Add(new DataColumn("Name", typeof(string)));
        datasource.Columns.Add(new DataColumn("Revenue", typeof(double)));

        datasource.Rows.Add("North America", "Chicago", "Consumer Electronics", "Bose 785593-0050", 92800);
        datasource.Rows.Add("North America", "New York", "Consumer Electronics", "Bose 785593-0050", 92800);
        datasource.Rows.Add("South America", "Santiago", "Consumer Electronics", "Bose 785593-0050", 19550);
        datasource.Rows.Add("North America", "Chicago", "Consumer Electronics", "Canon EOS 1500D", 98650);
        datasource.Rows.Add("North America", "Minnesota", "Consumer Electronics", "Canon EOS 1500D", 89110);
        datasource.Rows.Add("South America", "Santiago", "Consumer Electronics", "Canon EOS 1500D", 459000);
        datasource.Rows.Add("North America", "Chicago", "Consumer Electronics", "Haier 394L 4Star", 367050);
        datasource.Rows.Add("South America", "Quito", "Consumer Electronics", "Haier 394L 4Star", 729100);
        datasource.Rows.Add("South America", "Santiago", "Consumer Electronics", "Haier 394L 4Star", 578900);
        datasource.Rows.Add("North America", "Fremont", "Consumer Electronics", "IFB 6.5 Kg FullyAuto", 904930);
        datasource.Rows.Add("South America", "Buenos Aires", "Consumer Electronics", "IFB 6.5 Kg FullyAuto", 673800);
        datasource.Rows.Add("South America", "Medillin", "Consumer Electronics", "IFB 6.5 Kg FullyAuto", 82910);
        datasource.Rows.Add("North America", "Chicago", "Consumer Electronics", "Mi LED 40inch", 550010);
        datasource.Rows.Add("North America", "Minnesota", "Consumer Electronics", "Mi LED 40inch", 1784702);
        datasource.Rows.Add("South America", "Santiago", "Consumer Electronics", "Mi LED 40inch", 102905);
        datasource.Rows.Add("North America", "Chicago", "Consumer Electronics", "Sennheiser HD 4.40-BT", 178100);
        datasource.Rows.Add("South America", "Quito", "Consumer Electronics", "Sennheiser HD 4.40-BT", 234459);
        datasource.Rows.Add("North America", "Minnesota", "Mobile", "Iphone XR", 1734621);
        datasource.Rows.Add("South America", "Santiago", "Mobile", "Iphone XR", 109300);
        datasource.Rows.Add("North America", "Chicago", "Mobile", "OnePlus 7Pro", 499100);
        datasource.Rows.Add("South America", "Quito", "Mobile", "OnePlus 7Pro", 215000);
        datasource.Rows.Add("North America", "Minnesota", "Mobile", "Redmi 7", 81650);
        datasource.Rows.Add("South America", "Quito", "Mobile", "Redmi 7", 276390);
        datasource.Rows.Add("North America", "Minnesota", "Mobile", "Samsung S9", 896250);
        datasource.Rows.Add("South America", "Buenos Aires", "Mobile", "Samsung S9", 896250);
        datasource.Rows.Add("South America", "Quito", "Mobile", "Samsung S9", 716520);
        #endregion

        //Init template global settings
        workbook.Names.Add("TemplateOptions.KeepLineSize", "true");

        //Add data source
        workbook.AddDataSource("ds", datasource);
        //Invoke to process the template
        workbook.ProcessTemplate();

        // Save to an excel file
        workbook.Save("TemplateWorkWithConditionalFormatting.xlsx");

    }
}

// 数据模型
class ConstStringInfo
{
    public string Namespace { get; set; }
    public string TypeName { get; set; }
    public string FieldName { get; set; }
    public string Visibility { get; set; }
    public string Value { get; set; }
}